﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Security.Permissions;
using System.Text;
using System.Net;
using System.IO;
using System.Xml;
using System.Xml.Linq;
using System.Xml.XPath;
using System.Text.RegularExpressions;

namespace ProxyFileHost
{
    public class Handler : IHttpHandlerFactory, IHttpHandler
    {


        public IHttpHandler GetHandler(HttpContext context, string requestType, string url, string pathTranslated)
        {
            return this;
        }

        public void ReleaseHandler(IHttpHandler handler) { }

        public bool IsReusable
        {
            get { return true; }
        }





        public void ProcessRequest(HttpContext c)
        {

            c.Server.Transfer("~/test2.aspx");  
            const string XML_DIC = @"temp\xml";
            const string XML_RPC = @"";

            Func<string, string> RealRet = ReqXml =>
            {
                var url = XML_RPC;

                WebRequest req = WebRequest.Create(url);

                // 30 分钟超时
                req.Timeout = 30 * 60 * 1000;
                // POST 方法
                req.Method = "POST";

                using (Stream s = req.GetRequestStream())
                {
                    //写人XML
                    var bs = File.ReadAllBytes(ReqXml);
                    s.Write(bs, 0, bs.Length);
                }

                WebResponse result = req.GetResponse();

                using (StreamReader sr = new StreamReader(result.GetResponseStream()))
                {
                    //获得返回 XML
                    return sr.ReadToEnd();
                }
            };


            Func<HttpContext, string> getXmlName = context =>
            {
                DateTime dt = DateTime.Now;
                var guid = Guid.NewGuid();
                FileInfo ret = new FileInfo(context.Server.MapPath(string.Format(@"\{0}\{1:yyyyMMddHHmmssfff}{2}-{3}.xml", XML_DIC, dt, guid, "{0}")));
                ret.Directory.Create();
                return ret.FullName;
            };

            Func<string, IDictionary<string, string>> MediaToDic = path =>
            {
                using (XmlReader reader = XmlReader.Create(path))
                {
                    XDocument po = XDocument.Load(reader);
                    return (from m in po.XPathSelectElements("//member")
                            select new
                            {
                                key = m.Element("name").Value,
                                val = m.Element("value").Elements().First().Value
                            }).ToDictionary(m => m.key, m => m.val);
                }
            };

            Func<string, string> proxyRetunMedia = path =>
            {
                var dic = MediaToDic(path);
                Func<string, string> get = a => dic.ContainsKey(a) ? dic[a] : string.Empty;
                #region string xml_temp = ...
                string xml_temp =
@"
<?xml version=""1.0""?>
<methodResponse>
  <params>
    <param>
      <value>
        <struct>
          <member>
            <name>file</name>
            <value>
              <string>{0}</string>
            </value>
          </member>
          <member>
            <name>url</name>
            <value>
              <string>#proxy:{1}:#proxy</string>
            </value>
          </member>
          <member>
            <name>type</name>
            <value>
              <string>{2}</string>
            </value>
          </member>
        </struct>
      </value>
    </param>
  </params>
</methodResponse>
";
                #endregion
                return string.Format(xml_temp, get("name"), new FileInfo(path).Name, get("type")).Trim();
            };

            Func<string, string> getMethodName = path =>
            {
                using (XmlReader reader = XmlReader.Create(path))
                {
                    XDocument po = XDocument.Load(reader);

                    var methodNameElement = po.XPathSelectElement("//methodName");

                    return methodNameElement.Value;
                }
            };





            Func<string, bool> isNewPng = path =>
            {
                string type;

                return "metaWeblog.newMediaObject".Equals(getMethodName(path), StringComparison.CurrentCultureIgnoreCase)
                     && MediaToDic(path).TryGetValue("type", out type)
                     && "image/png".Equals(type, StringComparison.CurrentCultureIgnoreCase);
            };



            Func<string, string, string> new2edit = (ReqXml, ResXml) =>
            {
                string Post_Id = string.Empty;

                using (XmlReader reader = XmlReader.Create(ResXml))
                {
                    XDocument po = XDocument.Load(reader);

                    var IdElement = po.XPathSelectElement("//params/param/value/string");

                    Post_Id = IdElement.Value;
                }

                using (XmlReader reader = XmlReader.Create(ReqXml))
                {
                    XDocument po = XDocument.Load(reader);

                    var methodNameElement = po.XPathSelectElement("//methodName");

                    methodNameElement.SetValue("metaWeblog.editPost");

                    var IdElement = po.XPathSelectElement("//params/param/value/string");

                    IdElement.SetValue(Post_Id);

                    return po.ToString();
                }
            };

            Func<string, string, string> getBlog = (ReqXml, ResXml) =>
            {
                switch (getMethodName(ReqXml).ToUpper())
                {
                    case "METAWEBLOG.NEWPOST":
                        return new2edit(ReqXml, ResXml);
                    case "METAWEBLOG.EDITPOST":
                        return File.ReadAllText(ReqXml);
                    default:
                        return null;
                }
            };



            new Action<HttpContext>(context =>
            {

                var xmlFormt = getXmlName(context);

                var ReqXml = string.Format(xmlFormt, "Req");

                var ResXml = string.Format(xmlFormt, "Res");

                File.WriteAllText(ReqXml, new StreamReader(context.Request.InputStream).ReadToEnd());

                File.WriteAllText(ResXml, isNewPng(ReqXml) ? proxyRetunMedia(ReqXml) : RealRet(ReqXml));

                context.Response.WriteFile(ResXml);

            })(c);
            
        }






        static public void Get(HttpContext context)
        {
        }

        internal static void dosome()
        {

       
 
        }
 
       




    }
}